import pygame
import random
import numpy as np
from src.config import config as cfg

print("this is Snake.py")
K_LEFT = (-1, 0)
K_RIGHT = (1, 0)
K_UP = (0, -1)
K_DOWN = (0, 1)


# 蛇类
# 点以25为单位
class Snake(object):
    # 初始化各种需要的属性 [开始时默认向右/身体块x5]
    def __init__(self):
        # to right
        self.direction = K_RIGHT
        self.body = []
        self.img_queue = []
        self.width = cfg.UNIT
        # self.debug_add(19, 5)
        # self.debug_add(18, 5)
        # self.debug_add(18, 4)
        # self.debug_add(18, 3)
        # self.debug_add(18, 2)
        # self.debug_add(18, 1)
        self.fps = 2

        for x in range(cfg.SNAKE_SIZE):
            self.add_node()

    def reset(self):
        self.__init__()

    def punish_reset(self):
        self.fps = 2
        self.direction = K_RIGHT
        size = len(self.body) if len(self.body) < cfg.SNAKE_PUNISH_MAX_SIZE else cfg.SNAKE_PUNISH_MAX_SIZE
        self.body = []
        for i in range(size):
            self.add_node()

    def debug_add(self, i, j):
        node = (i, j)
        self.body.append(node)

    # 无论何时 都在前端增加蛇块
    def add_node(self):
        i, j = (0, 15)
        if self.body:
            i, j = self.body[0]
        node = (i, j)
        if self.direction == K_LEFT:
            node = (i - 1, j)
        elif self.direction == K_RIGHT:
            node = (i + 1, j)
        elif self.direction == K_UP:
            node = (i, j - 1)
        elif self.direction == K_DOWN:
            node = (i, j + 1)
        self.body.insert(0, node)

    # 删除最后一个块
    def del_node(self):
        self.body.pop()

    def is_crash_wall(self):
        r = random.randint(0, 1)
        i, j = self.body[0]
        next_i, next_j = i + self.direction[0], j + self.direction[1]

        # 贴左、贴右
        if next_i < 0 or next_i >= cfg.SCREEN_X // cfg.UNIT:
            # 角落，只有一个方向
            if next_j == 0:
                self.direction = K_DOWN
            elif next_j == cfg.SCREEN_X // cfg.UNIT - 1:
                self.direction = K_UP
            else:
                # 非角落，随机
                self.direction = K_UP if r == 0 else K_DOWN

        # 贴上、贴下
        if next_j < 0 or next_j >= cfg.SCREEN_Y // cfg.UNIT:
            # 角落，只有一个方向
            if next_i == 0:
                self.direction = K_RIGHT
            elif next_i == cfg.SCREEN_Y // cfg.UNIT - 1:
                self.direction = K_LEFT
            else:
                # 非角落，随机
                self.direction = K_LEFT if r == 0 else K_RIGHT

    # # 死亡判断
    # def is_dead(self):
    #     # 撞墙
    #     if self.body[0][0] not in range(cfg.SCREEN_X // cfg.UNIT):
    #         return True
    #     if self.body[0][0] not in range(cfg.SCREEN_Y // cfg.UNIT):
    #         return True
    #     # 撞自己
    #     if self.body[0] in self.body[1:]:
    #         return True
    #     return False

    # 移动！
    def move(self):
        self.is_crash_wall()
        self.add_node()
        self.del_node()

    # 改变方向 但是左右、上下不能被逆向改变
    def change_direction(self, cur_key):
        # 转成元组方向例如（-1，0）、（1，0）、（0，-1）、（0，1）
        new_direction = (0, 0)
        if cur_key == pygame.K_LEFT:
            new_direction = K_LEFT
        elif cur_key == pygame.K_RIGHT:
            new_direction = K_RIGHT
        elif cur_key == pygame.K_UP:
            new_direction = K_UP
        elif cur_key == pygame.K_DOWN:
            new_direction = K_DOWN
        else:
            return

        # 同向变快速
        if self.direction == new_direction:
            self.fps = 1
        # 反向变慢速
        elif self.direction[0] == -new_direction[0] and self.direction[1] == -new_direction[1]:
            self.fps = 2
        else:
            self.direction = new_direction
        #
        # # 如果
        # LR = [K_LEFT, K_RIGHT]
        # UD = [K_UP, K_DOWN]
        # if self.direction in LR + UD:
        #     if (cur_key in LR) and (self.direction in LR):
        #         return
        #     if (cur_key in UD) and (self.direction in UD):
        #         return
        #     self.direction = cur_key
        #
        # if cur_key == self.direction:
        #     self.fps = 1

    def get_status(self, index):
        body = self.body
        node = body[index]
        if index == 0:
            before = node
            after = body[index + 1]
        elif index == len(body) - 1:
            after = node
            before = body[index - 1]
        else:
            after = body[index + 1]
            before = body[index - 1]
        # 竖直的
        if before[0] == node[0] and after[0] == node[0]:
            return 1
        # 水平的
        if before[1] == node[1] and after[1] == node[1]:
            return 2
        # 角状
        return 3

    def get_img_queue(self):
        for i in range(len(self.body) - len(self.img_queue)):
            r = random.randint(0, 11)
            self.img_queue.append(r)
        return self.img_queue

    def is_crash_brick(self, bricks):
        i, j = self.body[0]
        # next_i, next_j = i + self.direction[0], j + self.direction[1]
        # 撞到病毒
        return bricks[j][i] != 0

    def is_enough(self):
        return len(self.body) == cfg.SNAKE_MAX_SIZE
